package com.homwee.serialportinspection.serialport;

import android.os.RemoteException;
import android.util.Log;

import com.mediatek.twoworlds.factory.MtkTvFApiEventListener;
import com.mediatek.twoworlds.factory.MtkTvFApiPeripheral;
import com.mediatek.twoworlds.factory.clientwrapper.MtkTvFApiManagerProxy;
import com.mediatek.twoworlds.factory.common.MtkTvFApiPeripheralTypes;
import com.mediatek.twoworlds.factory.model.MtkTvFApiEventTypeEnm;
import com.mediatek.twoworlds.factory.model.MtkTvFApiUartBaudRateEnm;

import com.mediatek.twoworlds.factory.model.MtkTvFApiUartDeviceTypeEnm;

import com.mediatek.twoworlds.factory.model.MtkTvFApiUartPortTypeEnm;
import com.mediatek.twoworlds.tv.MtkTvConfig;
import com.mediatek.twoworlds.tv.common.MtkTvConfigType;
import java.util.ArrayList;

import vendor.mediatek.tv.mtktvfactory.V1_0.MtkTvFApiEventCommonObject;

public class MtkSerialPort extends SerialPort {
    private static final String TAG = "MtkSerialPort";

    private static final int UART_MODE_STD_FACTORY = 0xd;
    private  int BUFFER_SIZE = 11;

    MtkTvFApiEventListener mListener;
    private boolean mMtkTvFApiEventListenerFlag = false;

    private class MtkTvFApiListener extends MtkTvFApiEventListener {
        private static final String TAG = "MtkTvFApiLisnter";

        @Override
        public int onPeripheralEvent(
            int evtType, com.mediatek.twoworlds.factory.model.MtkTvFApiEventCommonObject arg1, com.mediatek.twoworlds.factory.model.MtkTvFApiEventCommonObject arg2, com.mediatek.twoworlds.factory.model.MtkTvFApiEventCommonObject arg3, com.mediatek.twoworlds.factory.model.MtkTvFApiEventCommonObject arg4)
                throws RemoteException {
            Log.d(TAG, "onPeripheralEvent: Event type = " + evtType);

            if (evtType == MtkTvFApiEventTypeEnm.E_MTK_TV_FAPI_EVENT_TYPE_PRPHRL_FACTORY_UART) {
                int size = arg1.vecArg.size();
                byte[] cmd = new byte[size];

                Log.d(TAG, "[FACTORY_UART] size" + size);
                for (int i = 0; i < size; i++) {
                    cmd[i] = arg1.vecArg.get(i);
                    Log.d(TAG, "cmd["+i+"] " + cmd[i]);
                }
                String uartData = new String(cmd);
                Log.d(TAG, "[FACTORY_UART] data " + uartData);
                for (Listener listener : mListeners) {
                    //listener.onString(uartData);
                    listener.onData(cmd);
                }
            }

            return 0;
        }
    }

    @Override
    public void init() {
        if (mMtkTvFApiEventListenerFlag == true) {
            Log.d(TAG, "The listener is already be registered!");
            return;
        }
        mListener = new MtkTvFApiListener();
        mMtkTvFApiEventListenerFlag = true;
        Log.d(TAG, "Register MtkSerialPort Listener");
    }

    @Override
    public void uninit() {
        if (mMtkTvFApiEventListenerFlag == false) {
            Log.d(TAG, "The listener is free!");
            return;
        }
        mListener.removeListener();
        mMtkTvFApiEventListenerFlag = false;
        Log.d(TAG, "Remove MtkSerialPort Listener");
    }

    @Override
    public boolean start() {
        //Open Uart
        int ret;

        MtkTvFApiEventCommonObject obj1;
        obj1 = new MtkTvFApiEventCommonObject();

        MtkTvFApiEventCommonObject obj2;
        obj2 = new MtkTvFApiEventCommonObject();

        MtkTvFApiEventCommonObject obj3;
        obj3 = new MtkTvFApiEventCommonObject();

        MtkTvFApiEventCommonObject obj4;
        obj4 = new MtkTvFApiEventCommonObject();

        obj1.vecArg.add((byte) 0x36);
        obj1.vecArg.add((byte) 0x96);
        obj1.vecArg.add((byte) 0x00);
        obj1.vecArg.add((byte) 0x00);
        obj1.vecArg.add((byte) 0x00);
        obj1.vecArg.add((byte) 0x00);
        try {
            ret = MtkTvFApiManagerProxy
                    .getInstance()
                    .getMtkTvFApiManager()
                    .a_hidl_a_mtktvfapi_mngr_post_event(
                            MtkTvFApiEventTypeEnm.E_MTK_TV_FAPI_EVENT_TYPE_PRPHRL_FACTORY_UART, obj1, obj2, obj3, obj4);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        boolean bOnOff = true;
        byte baudrate = MtkTvFApiUartBaudRateEnm.E_MTK_TV_FAPI_UART_BAUDRATE_115200;
        byte port = MtkTvFApiUartPortTypeEnm.E_MTK_TV_FAPI_UART_PORT_1;
        //byte uart = MtkTvFApiUartDeviceTypeEnm.E_MTK_TV_FAPI_UART_PIU_UART1;

        //Switch to uart port1 and enable factory uart on it
        //ret = MtkTvConfig.getInstance().setConfigValue(MtkTvConfigType.CFG_MISC_EX_UART_FACTORY_MODE, 1);
        //Log.d(TAG, "[FactoryUT] SetUart Config ret = "+ret);

        int actual;
         actual = MtkTvFApiPeripheral.getInstance().switch2Ttys1(true);
        actual |= MtkTvFApiPeripheral
                .getInstance()
                .setStdFactoryUartCallback(bOnOff, baudrate, port);

        ret = MtkTvFApiPeripheral.getInstance().setStdFactoryCustomConfig(
                MtkTvFApiPeripheralTypes.StdFactoryUartMode.MODE_DEFAULT, (byte) UART_MODE_STD_FACTORY, BUFFER_SIZE);
        Log.d(TAG, "[FactoryUT] SetFactoryUartOpen success! actual "+ actual+ " setStdFactoryCustomConfig " +ret);

        return true;
    }

    @Override
    public boolean stop() {

        int ret;
        boolean actual;
        boolean expected = true;
        //MtkTvFApiEventListener mlistener = new MtkTvFApiListener();

        //Close Uart
        boolean bOnOff = false;
        byte baudrate = MtkTvFApiUartBaudRateEnm.E_MTK_TV_FAPI_UART_BAUDRATE_115200;
        byte port = MtkTvFApiUartPortTypeEnm.E_MTK_TV_FAPI_UART_PORT_1;
        byte uart = MtkTvFApiUartDeviceTypeEnm.E_MTK_TV_FAPI_UART_PIU_UART1;

        ret = MtkTvFApiPeripheral
                .getInstance()
                .setStdFactoryUartCallback(bOnOff, baudrate, port);

         ret |= MtkTvFApiPeripheral.getInstance().switch2Ttys1(false);
       // MtkTvConfig.getInstance().setConfigValue(
       //         MtkTvConfigType.CFG_MISC_EX_UART_FACTORY_MODE, 0);
        Log.d(TAG, "[FactoryUT] SetFactoryUartClose success!");

        return true;
    }

    @Override
    public byte[] read(int size) {
        return new byte[0];
    }

    @Override
    public int write(byte[] data) {
        int ret;

        ArrayList<Byte> inputData = new ArrayList<Byte>();
        byte[] byteArray = data;
        for (int i = 0; i < data.length; i++) {
            inputData.add(byteArray[i]);
        }
        Log.d(TAG, "[FactoryUT] write "+data+" inputData "+inputData);

        //Usage: open uart -> write uart -> close uart
        ret = MtkTvFApiPeripheral.getInstance().writeStdFactoryUart(inputData);
        Log.d(TAG, "[FactoryUT] write ret " +ret);

        return ret;
    }

    @Override
    public String readString() {
        String command = null;
        return command;
    }

    @Override
    public int writeString(String string) {
        int ret = 0;

        Log.d(TAG, "writeString: " + string);

        if (string == null || string.equals("")) {
            return 0;
        }

        ret = write(string.getBytes());

        if (ret != -1) {
            return string.length();
        }

        return ret;
    }

	public void setBuffSize(int size){
        BUFFER_SIZE = size;
	}
}
